#ifndef _STEPPER_MOTOR_H_
#define _STEPPER_MOTOR_H_

#include "main.h"

//大的驱动器 --- 200 8细分 --- S5-S8 1011
//小的驱动器 --- 200 8细分 --- S5-S8 0011 

#define TIM_FREQ            72000000U                       /* 定时器主频 */
#define MAX_STEP_ANGLE      0.036                           /* 最小步距(1.8/MICRO_STEP) */
#define PAI                 3.1415926                       /* 圆周率*/
#define FSPR                200                             /* 步进电机单圈步数 */
#define MICRO_STEP          50                              /* 步进电机驱动器细分数 */
#define T1_FREQ             (TIM_FREQ/72)                   /* 频率ft值 */
#define SPR                 (FSPR*MICRO_STEP)               /* 旋转一圈需要的脉冲数 */

/* 数学常数 */

#define ALPHA               ((float)(2*PAI/SPR))            /* α = 2*pi/spr */
#define A_T_x10             ((float)(10*ALPHA*T1_FREQ))
#define T1_FREQ_148         ((float)((T1_FREQ*0.69)/10))    /* 0.69为误差修正值 */
#define A_SQ                ((float)(2*100000*ALPHA))
#define A_x200              ((float)(200*ALPHA))            /* 2*10*10*a/10 */


typedef struct
{
    __IO uint8_t  run_state;                                /* 电机旋转状态 */
    __IO uint8_t  dir;                                      /* 电机旋转方向 */
    __IO int32_t  step_delay;                               /* 下个脉冲周期（时间间隔），启动时为加速度 */
    __IO uint32_t decel_start;                              /* 开始减速位置 */
    __IO int32_t  decel_val;                                /* 减速阶段步数 */
    __IO int32_t  min_delay;                                /* 速度最快，计数值最小的值(最大速度，即匀速段速度) */
    __IO int32_t  accel_count;                              /* 加减速阶段计数值 */
} speedRampData;

enum STA
{
    STOP = 0,                                               /* 加减速曲线状态：停止*/
    ACCEL,                                                  /* 加减速曲线状态：加速阶段*/
    DECEL,                                                  /* 加减速曲线状态：减速阶段*/
    RUN                                                     /* 加减速曲线状态：匀速阶段*/
};

enum DIR
{
 CCW = 0,                                                   /* 逆时针 */ 
 CW                                                         /* 顺时针 */
};

enum EN
{
 EN_ON = 0,                                                 /* 失能脱机引脚 */
 EN_OFF                                                     /* 使能脱机引脚 使能后电机停止旋转 */
};

//F103RCT6控制板 脉冲口 --- PC6 PC7 PA8 PA11
//F103RCT6控制板 脉冲口对应定时器 --- tim8 tim8 tim1 tim1
//F103RCT6控制板 脉冲口对应定时器通道 --- ch1 ch2 ch1 ch4
//控制脉冲口输出使能端 --- PC13
//使能 --- PC1 PA1 PB3 PC10
//方向 --- PC3 PA3 PC12 PA12

//从左往右 1 - 4 
//从左往右 使能 方向 脉冲

#define STEPPER_DIR1_GPIO_PORT                  GPIOC
#define STEPPER_DIR2_GPIO_PORT                  GPIOA
#define STEPPER_DIR3_GPIO_PORT                  GPIOC
#define STEPPER_DIR4_GPIO_PORT                  GPIOA
#define STEPPER_EN1_GPIO_PORT                   GPIOC
#define STEPPER_EN2_GPIO_PORT                   GPIOA
#define STEPPER_EN3_GPIO_PORT                   GPIOB
#define STEPPER_EN4_GPIO_PORT                   GPIOC


/*----------------------- 方向引脚控制 -----------------------------------*/
/* 由于我们使用的是共阳极解法，并且硬件对电平做了取反操作，所以当 x = 1 有效，x = 0时无效*/  
#define ST1_DIR(x)    do{ x ? \
                              HAL_GPIO_WritePin(STEPPER_DIR1_GPIO_PORT, STEP1_DIR_Pin, GPIO_PIN_SET) : \
                              HAL_GPIO_WritePin(STEPPER_DIR1_GPIO_PORT, STEP1_DIR_Pin, GPIO_PIN_RESET); \
                          }while(0)  

#define ST2_DIR(x)    do{ x ? \
                              HAL_GPIO_WritePin(STEPPER_DIR2_GPIO_PORT, STEP2_DIR_Pin, GPIO_PIN_SET) : \
                              HAL_GPIO_WritePin(STEPPER_DIR2_GPIO_PORT, STEP2_DIR_Pin, GPIO_PIN_RESET); \
                          }while(0)  

#define ST3_DIR(x)    do{ x ? \
                              HAL_GPIO_WritePin(STEPPER_DIR3_GPIO_PORT, STEP3_DIR_Pin, GPIO_PIN_SET) : \
                              HAL_GPIO_WritePin(STEPPER_DIR3_GPIO_PORT, STEP3_DIR_Pin, GPIO_PIN_RESET); \
                          }while(0)  

#define ST4_DIR(x)    do{ x ? \
                              HAL_GPIO_WritePin(STEPPER_DIR4_GPIO_PORT, STEP4_DIR_Pin, GPIO_PIN_SET) : \
                              HAL_GPIO_WritePin(STEPPER_DIR4_GPIO_PORT, STEP4_DIR_Pin, GPIO_PIN_RESET); \
                          }while(0)  

/*----------------------- 脱机引脚控制 -----------------------------------*/
/* 由于我们使用的是共阳极解法，并且硬件对电平做了取反操作，所以当 x = 1 有效，x = 0时无效*/                          
#define ST1_EN(x)      do{ x ? \
                          HAL_GPIO_WritePin(STEPPER_EN1_GPIO_PORT, STEP1_EN_Pin, GPIO_PIN_SET) : \
                          HAL_GPIO_WritePin(STEPPER_EN1_GPIO_PORT, STEP1_EN_Pin, GPIO_PIN_RESET); \
                        }while(0)    

#define ST2_EN(x)      do{ x ? \
                          HAL_GPIO_WritePin(STEPPER_EN2_GPIO_PORT, STEP2_EN_Pin, GPIO_PIN_SET) : \
                          HAL_GPIO_WritePin(STEPPER_EN2_GPIO_PORT, STEP2_EN_Pin, GPIO_PIN_RESET); \
                        }while(0)    

#define ST3_EN(x)      do{ x ? \
                          HAL_GPIO_WritePin(STEPPER_EN3_GPIO_PORT, STEP3_EN_Pin, GPIO_PIN_SET) : \
                          HAL_GPIO_WritePin(STEPPER_EN3_GPIO_PORT, STEP3_EN_Pin, GPIO_PIN_RESET); \
                        }while(0)    

#define ST4_EN(x)      do{ x ? \
                          HAL_GPIO_WritePin(STEPPER_EN4_GPIO_PORT, STEP4_EN_Pin, GPIO_PIN_SET) : \
                          HAL_GPIO_WritePin(STEPPER_EN4_GPIO_PORT, STEP4_EN_Pin, GPIO_PIN_RESET); \
                        }while(0)      


void step1_create_t_ctrl_param(int32_t step, uint32_t accel, uint32_t decel, uint32_t speed);  
void step2_create_t_ctrl_param(int32_t step, uint32_t accel, uint32_t decel, uint32_t speed);  
void step3_create_t_ctrl_param(int32_t step, uint32_t accel, uint32_t decel, uint32_t speed);  
void step4_create_t_ctrl_param(int32_t step, uint32_t accel, uint32_t decel, uint32_t speed);  

#endif


